#ifndef _SYS_RANGE_H_
#define _SYS_RANGE_H_

#include "FanObj.h"
#include "SysTypes.h"

#define RANGE_VTABLE(self)   ((RangeVTable*)((FanObj*)self)->vtable)


extern Type*    Range_classType;
extern VTable*  Range_classVTable;


/* [sys::Range] Attributes */
struct Range
{
  FanObj        super;
  Int           start;
  Int           end;
  Bool          exclusive;
};


/* [sys::Range] Virtual-table */
typedef struct RangeVTable
{
  FanObjVTable  super;
} RangeVTable;


/* [sys::Range] Methods and fields */
void            Range_makeInclusive(Range* self, Int start, Int end);
void            Range_makeExclusive(Range* self, Int start, Int end);
void            Range_make(Range* self, Int start, Int end, Bool exclusive);
Bool            Range_equals(Obj self, NullableObj obj);
Int             Range_hash(Obj self);
Str*            Range_toStr(Obj self);
Range*          Range_fromStr_1(Str* s);
Range*          Range_fromStr(Str* s, Bool checked);
Int             Range_start(Range* self);
Int             Range_end(Range* self);
Bool            Range_inclusive(Range* self);
Bool            Range_exclusive(Range* self);
Bool            Range_isEmpty(Range* self);
NullableInt     Range_min(Range* self);
NullableInt     Range_max(Range* self);
NullableInt     Range_first(Range* self);
NullableInt     Range_last(Range* self);
Bool            Range_contains(Range* self, Int i);
Range*          Range_offset(Range* self, Int offset);
void            Range_each(Range* self, Func* c);
List*           Range_map(Range* self, Func* c);
List*           Range_toList(Range* self);
Int             Range_random(Range* self);


/* [sys::Range] Extra methods */
Range*          Range_new(Int start, Int end, Bool exclusive);
Int             Range_absStart(Range* self, Int size);
Int             Range_absEnd(Range* self, Int size);


/* [sys::Range] Type-system functions */
Type*           Range_initType(void);
VTable*         Range_initVTable(void);
void            Range_initStatic(void);


#endif
